#include "atom.h"
#include "drv_psram.h"
#include "esp_heap_caps.h"
#include "multi_heap.h"
#include "syslog.h"

static Ram _psram;

#include "syslog.h"
#define LOG_LEVEL LOG_DEBUG

static void *psram_alloc(Ram *dev, size_t size)
{
    void *ptr = heap_caps_malloc(size, MALLOC_CAP_SPIRAM);

    SYSLOG(LOG_LEVEL, "psram_alloc: allocated %d bytes at %p", size, ptr);

    return ptr;
}

static void *psram_realloc(Ram *dev, void *mem, size_t size)
{
    void *ptr = heap_caps_realloc(mem, size, MALLOC_CAP_SPIRAM);
   
    SYSLOG(LOG_LEVEL, "psram_realloc: reallocated to %d bytes at %p", size, ptr);
    
    return ptr;
}

static void psram_free(Ram *dev, void *mem)
{
    SYSLOG(LOG_LEVEL, "psram_free: freeing memory at %p", mem);

    heap_caps_free(mem);
}

static void psram_useage(Ram *dev, RamInfo *info)
{
    multi_heap_info_t heap_info;
    heap_caps_get_info(&heap_info, MALLOC_CAP_SPIRAM);
    info->free_bytes = heap_info.total_free_bytes;
    info->total_bytes = heap_info.total_allocated_bytes  + heap_info.total_free_bytes;
}

void Esp32PsramCreate(void)
{
    _psram.Protected.alloc = psram_alloc;
    _psram.Protected.realloc = psram_realloc;
    _psram.Protected.free = psram_free;
    _psram.Protected.useage = psram_useage;

    RamCreate(&_psram, "psram");
}